import {useModel} from '@@/exports';
import {DownloadOutlined, PlusOutlined, UploadOutlined} from '@ant-design/icons';
import type {ActionType, ProColumns} from '@ant-design/pro-components';
import {EditableProTable, ParamsType} from '@ant-design/pro-components';
import {
  Button,
  DatePicker,
  DatePickerProps,
  Form,
  message,
  notification,
  Popconfirm,
  Space,
  Upload,
  UploadProps
} from 'antd';
import React, {useEffect, useRef, useState} from 'react';
import {listProductionLineByMonthlyPlanningUsingGET} from "@/services/model/productionLineController";
import {listBaseStepByMonthlyPlanningUsingGET} from "@/services/model/baseStepController";
import {
  addDailyPlanningUsingPOST,
  deleteDailyPlanningUsingDELETE,
  editDailyPlanningUsingPUT,
  listDailyPlanningUsingGET
} from "@/services/model/dailyPlanningController";
import dayjs from "dayjs";
import {errorConfig} from "@/requestErrorConfig";
import CustomSelect from "@/pages/components/CustomSelect";

const LeftTable: React.FC = () => {
  const {initialState} = useModel('@@initialState');
  const actionRef = useRef<ActionType>();
  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
  const [dataSource, setDataSource] = useState<readonly API.DailyPlanningDTO[]>([]);
  const [productionLineList, setProductionLineList] = useState<readonly API.ProductionLineDTO[]>([]);

  const [selectAddProductionLineValue, setSelectAddProductionLineValue] = useState('');
  const [selectAddKeyProcessValue, setSelectAddKeyProcessValue] = useState<string>('');
  const [selectAddPlanningDate, setSelectAddPlanningDate] = useState<string>('');

  const [selectSearchProductionLineValue, setSelectSearchProductionLineValue] = useState('');
  const [selectSearchKeyProcessValue, setSelectSearchKeyProcessValue] = useState<string>('');
  const [selectSearchPlanningDate, setSelectSearchPlanningDate] = useState<string>('');

  const [selectAddDateValue, setSelectAddDateValue] = useState<dayjs.Dayjs>();
  const [selectSearchDateValue, setSelectSearchDateValue] = useState<dayjs.Dayjs>();
  const [addBaseStepList, setAddBaseStepList] = useState<readonly API.BaseStepDTO[]>([]);
  const [searchBaseStepList, setSearchBaseStepList] = useState<readonly API.BaseStepDTO[]>([]);

  const [form] = Form.useForm();
  // 弹出上传信息数据
  type NotificationType = 'success' | 'info' | 'warning' | 'error';
  const [api, contextHolder] = notification.useNotification();
  const openNotification = (type: NotificationType, info: string) => {
    api[type]({
      message: "上传信息",
      description: info,
      duration: 0,
      placement: "bottomRight"
    });
  };
  useEffect(() => {
    listProductionLineByMonthlyPlanningUsingGET({
      commitUserId: initialState?.currentUser?.id,
    }).then((result) => {
      if (result.code === 0 && result.data) {
        setProductionLineList(result.data);
      }
    });
  }, []);

  useEffect(() => {
    if (selectAddProductionLineValue === '' || selectAddPlanningDate === '') {
      setAddBaseStepList([]);
      return;
    }
    listBaseStepByMonthlyPlanningUsingGET({
      currentUserId: initialState?.currentUser?.id,
      productionLineCode: selectAddProductionLineValue,
      planningDate: selectAddPlanningDate,
    }).then((result) => {
      if (result.code === 0 && result.data) {
        setAddBaseStepList(result.data);
      }
    });
  }, [selectAddProductionLineValue, selectAddPlanningDate])

  useEffect(() => {
    if (selectSearchProductionLineValue === '' || selectSearchPlanningDate === '') {
      setSearchBaseStepList([]);
      return;
    }
    listBaseStepByMonthlyPlanningUsingGET({
      currentUserId: initialState?.currentUser?.id,
      productionLineCode: selectSearchProductionLineValue,
      planningDate: selectSearchPlanningDate,
    }).then((result) => {
      if (result.code === 0 && result.data) {
        setSearchBaseStepList(result.data);
      }
    });
  }, [selectSearchProductionLineValue, selectSearchPlanningDate])

  const AddProductionLineCodeList = () => {
    return (
      <CustomSelect name={"产线编码"}
                    selectDate={selectAddProductionLineValue}
                    setSelectData={setSelectAddProductionLineValue}
                    datalist={productionLineList.map(item => {
                      return {id: item.code, name: item.code}
                    })}/>
    );
  };
  const SearchProductionLineCodeList = () => {
    return (
      <CustomSelect name={"产线编码"}
                    selectDate={selectSearchProductionLineValue}
                    setSelectData={setSelectSearchProductionLineValue}
                    datalist={productionLineList.map(item => {
                      return {id: item.code, name: item.code}
                    })}/>
    );
  };
  const AddProductionLineNameList = () => {
    return (
      <CustomSelect name={"产线名称"}
                    selectDate={selectAddProductionLineValue}
                    setSelectData={setSelectAddProductionLineValue}
                    datalist={productionLineList.map(item => {
                      return {id: item.code, name: item.name}
                    })}/>
    );
  };
  const SearchProductionLineNameList = () => {
    return (
      <CustomSelect name={"产线名称"}
                    selectDate={selectSearchProductionLineValue}
                    setSelectData={setSelectSearchProductionLineValue}
                    datalist={productionLineList.map(item => {
                      return {id: item.code, name: item.name}
                    })}/>

    );
  };
  const onSelectAddDateChange: DatePickerProps['onChange'] = (date, dateString) => {
    setSelectAddPlanningDate(dateString)
    if (date) {
      setSelectAddDateValue(date)
    } else {
      setSelectAddDateValue(undefined)
    }
  };
  const AddDateSelect = () => {
    return <DatePicker value={selectAddDateValue} onChange={onSelectAddDateChange}/>
  }
  const onSelectSearchDateChange: DatePickerProps['onChange'] = (date, dateString) => {
    setSelectSearchPlanningDate(dateString)
    if (date) {
      setSelectSearchDateValue(date)
    } else {
      setSelectSearchDateValue(undefined)
    }
  };
  const SearchDateSelect = () => {
    return <DatePicker value={selectSearchDateValue} onChange={onSelectSearchDateChange} picker="month"/>
  }
  const AddKeyProcessList = () => {
    return (
      <CustomSelect name={"工序名称"}
                    disabled={addBaseStepList === null || addBaseStepList.length === 0}
                    selectDate={selectAddKeyProcessValue}
                    setSelectData={setSelectAddKeyProcessValue}
                    datalist={addBaseStepList.map(item => {
                      return {id: item.code, name: item.name + " [" + item.code + "]"}
                    })}/>
    );
  };
  const SearchKeyProcessList = () => {
    return (
      <CustomSelect name={"工序名称"}
                    disabled={searchBaseStepList === null || searchBaseStepList.length === 0}
                    selectDate={selectSearchKeyProcessValue}
                    setSelectData={setSelectSearchKeyProcessValue}
                    datalist={searchBaseStepList.map(item => {
                      return {id: item.code, name: item.name + " [" + item.code + "]"}
                    })}/>
    );
  };
  const initListDailyPlanning = async (params: ParamsType & {
    pageSize?: number | undefined,
    current?: number | undefined,
    keyword?: string | undefined
  }) => {

    const result = await listDailyPlanningUsingGET({
      commitUserId: initialState?.currentUser?.id,
      productionLineCode: selectSearchProductionLineValue && selectSearchProductionLineValue,
      planningDate: selectSearchPlanningDate,
      keyStepCode: selectSearchKeyProcessValue,
      pageSize: params.pageSize,
      pageNum: params.current,
    });
    if (result.data && result.data.list) {
      result.data.list.forEach(item => {
        if (item.targetRate) {
          item.targetRate = Number((item.targetRate * 100).toFixed(2));
        }
      })
      return {
        data: result.data.list,
        total: result.data.total,
        success: result.code === 0,
      }
    }
    return {}
  };
  const onDelete = async (record: API.DailyPlanningDTO) => {
    const result = await deleteDailyPlanningUsingDELETE({
      id: record.id,
      currentUserId: initialState?.currentUser?.id,
    });
    if (result.code === 0 && result.data) {
      message.success('删除成功');
      actionRef.current?.reload();
    } else {
      message.warning(result.message);
    }
  };
  const onSave = async (record: API.DailyPlanningDTO) => {
    const currentUserId = initialState?.currentUser?.id;
    const newDailyKeyProcessRate: API.AddDailyPlanningQuery = {
      productionLineCode: selectAddProductionLineValue,
      keyStepCode: selectAddKeyProcessValue,
      planningDate: selectAddPlanningDate,
      targetRate: record.targetRate ? Number((record.targetRate * 0.01).toFixed(2)) : undefined,
      capacity: record.capacity,
      scheduling: record.scheduling,
      currentUserId,
    };
    const result = await addDailyPlanningUsingPOST(newDailyKeyProcessRate);
    if (result.code === 0 && result.data) {
      message.success('添加成功');
    } else {
      message.warning(result.message);
    }
    actionRef.current?.reload();
  };
  const onEdit = async (record: API.DailyPlanningDTO) => {
    const currentUserId = initialState?.currentUser?.id;
    const newDailyPlanning: API.EditDailyPlanningQuery = {
      id: record.id,
      productionLineCode: record.productionLineCode,
      keyStepCode: record.keyStepCode,
      planningDate: record.planningDate,
      targetRate: record.targetRate ? Number((record.targetRate * 0.01).toFixed(2)) : undefined,
      capacity: record.capacity,
      scheduling: record.scheduling,
      currentUserId,
    };
    const result = await editDailyPlanningUsingPUT(newDailyPlanning);
    if (result.code === 0 && result.data) {
      message.success('修改成功');
    } else {
      message.warning("修改失败");
    }
    actionRef.current?.reload();
  };

  const columns: ProColumns<API.DailyPlanningDTO>[] = [
    {
      title: '序号',
      key: 'index',
      render: (dom, entity, index) => (
        index + 1
      ),
      editable: false
    },
    {
      title: '产线编码',
      key: 'productionLineCode',
      dataIndex: 'productionLineCode',
      valueType: 'text',
      editable: (text, record: any) => {
        return record.type === "addDailyKeyProcessRate";
      },
      renderFormItem: (_, {isEditable}) => isEditable ? <AddProductionLineCodeList/> : <SearchProductionLineCodeList/>,
    },
    {
      title: '产线名称',
      key: 'productionLineName',
      dataIndex: 'productionLineName',
      valueType: 'text',
      editable: (text, record: any) => {
        return record.type === "addDailyKeyProcessRate";
      },
      renderFormItem: (_, {isEditable}) => isEditable ? <AddProductionLineNameList/> : <SearchProductionLineNameList/>,
    },
    {
      title: '计划日期',
      key: 'planningDate',
      dataIndex: 'planningDate',
      valueType: 'date',
      editable: (text, record: any) => {
        return record.type === "addDailyKeyProcessRate";
      },
      renderFormItem: (_, {isEditable}) => isEditable ? <AddDateSelect/> : <SearchDateSelect/>,
    },
    {
      title: '关键工序名称',
      key: 'keyStepName',
      dataIndex: 'keyStepName',
      valueType: 'text',
      editable: (text, record: any) => {
        return record.type === "addDailyKeyProcessRate";
      },
      renderFormItem: (_, {isEditable}) => isEditable ? <AddKeyProcessList/> : <SearchKeyProcessList/>,
    },
    {
      title: '目标良率',
      key: 'targetRate',
      dataIndex: 'targetRate',
      valueType: 'percent',
      hideInSearch: true,
    },
    {
      title: '计划产能',
      key: 'capacity',
      dataIndex: 'capacity',
      valueType: 'digit',
      hideInSearch: true,
    },
    {
      title: '计划排产',
      key: 'scheduling',
      dataIndex: 'scheduling',
      valueType: 'digit',
      hideInSearch: true,
    },
    {
      title: '操作',
      valueType: 'option',
      render: (text, record, _, action) => [
        <a
          key="editable"
          onClick={(e) => {
            e.stopPropagation()
            form.resetFields();
            setSelectAddProductionLineValue('');
            action?.startEditable?.(record.id);
          }}
        >
          编辑
        </a>,
        <Popconfirm
          key={'onDelete'}
          title="你想要删除这个产线配置吗"
          onConfirm={() => onDelete(record)}
          okText="Yes"
          cancelText="No"
        >
          <a key="deletable" onClick={(e) => e.stopPropagation()}>删除</a>
        </Popconfirm>,
      ],
    },
  ];
  const props: UploadProps = {
    withCredentials: true,
    name: 'file',
    data: {
      currentUserId: initialState?.currentUser?.id,
    },
    action: errorConfig.baseURL + '/daily-planning/upload',
    headers: {
      authorization: 'authorization-text',
    },
    onChange(info) {
      if (info.file.status !== 'uploading') {
      }
      if (info.file.status === 'done') {
        message.success(`${info.file.name} 上传成功`);
        if (info.file.response.code === 0 && info.file.response.data) {
          actionRef.current?.reload();
          openNotification('success',info.file.response.data);
        } else {
          openNotification('warning',"提交数据无效，请检查上传文件！");
        }
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} 上传失败`);
      }
    },
  };
  return (
    <>
      {contextHolder}
      <div style={{display: "flex", justifyContent: "space-between", marginBottom: '5px'}}>
        <Space>
          <Button
            type="primary"
            onClick={() => {
              form.resetFields();
              setSelectAddProductionLineValue('');
              setSelectAddKeyProcessValue('');
              setSelectAddDateValue(undefined);
              setSelectAddPlanningDate('');
              actionRef.current?.addEditRecord?.({
                id: (Math.random() * 1000000).toFixed(0),
                type: 'addDailyKeyProcessRate',
              });
            }}
            icon={<PlusOutlined/>}
          >
            新增 日计划产能和排产
          </Button>
          <Button
            key="reset"
            onClick={() => {
              setSelectAddProductionLineValue('');
              setSelectAddKeyProcessValue('');
              setSelectAddDateValue(undefined)
              setSelectAddPlanningDate('')
              form.resetFields();
            }}
          >
            重置表单
          </Button>
        </Space>
        <Space>
          <Button
            type="dashed"
            key="downloadDailyPlanning"
            icon={<DownloadOutlined/>}
            onClick={() => {
              const url = errorConfig.baseURL + '/daily-planning/download?';
              let params = "commitUserId=" + initialState?.currentUser?.id + "&";
              if (selectSearchProductionLineValue) {
                params += "productionLineCode=" + selectSearchProductionLineValue + "&";
              }
              if (selectSearchPlanningDate) {
                params += "planningDate=" + selectSearchPlanningDate + "&";
              }
              if (selectSearchKeyProcessValue) {
                params += "keyStepCode=" + selectSearchKeyProcessValue + "&";
              }
              window.location.href = url + params;
            }}
          >
            导出数据
          </Button>
          <Upload {...props}>
            <Button icon={<UploadOutlined/>}>上传数据</Button>
          </Upload>
        </Space>
      </div>
      <EditableProTable<API.DailyPlanningDTO>
        id={"table-id"}
        rowKey="id"
        scroll={{y: 'calc(100vh - 260px)'}}
        search={{
          labelWidth: 'auto',
        }}
        onReset={() => {
          setSelectSearchPlanningDate('')
          setSelectSearchDateValue(undefined)
          setSelectSearchKeyProcessValue('')
          setSelectSearchProductionLineValue('')
        }}
        actionRef={actionRef}
        recordCreatorProps={false}
        columns={columns}
        pagination={{
          defaultPageSize: 50,
        }}
        request={(params: ParamsType & {
          pageSize?: number | undefined,
          current?: number | undefined,
          keyword?: string | undefined
        }) => initListDailyPlanning(params)}
        value={dataSource}
        onChange={setDataSource}
        editable={{
          form,
          editableKeys,
          onSave: async (key, row: any) => {
            if (row.type === 'addDailyKeyProcessRate') {
              await onSave(row);
              return;
            } else {
              await onEdit(row);
            }
            // 如果是原始数据没有username等属性值，则修改
          },
          onChange: setEditableRowKeys,
          actionRender: (row, config, dom) => [dom.save, dom.cancel],
        }}
      />
    </>
  );
};

export default LeftTable;
